#include <stdio.h>
#include <stdlib.h>
#include "dominion.h"
#include "rngs.h"
#include "math.h"
#include <assert.h>
#include <string.h>

void prepRandom(int strm, int seed){
  SelectStream(strm);
  PutSeed((long)seed);
}

int getRandomNumber(int min, int max){
	int number = floor(Random() * (max-min));
	number += min;
	return number;

}

void randomizeSupply(struct gameState *g){
	int i;
	for(i=0; i < 27; i++){
		g->supplyCount[i] = getRandomNumber(0, 40);
	}
}

void randomizeHands(struct gameState *g){
	int players = g->numPlayers;
	int i, j;
	for(i=0; i < players; i++){
		g->handCount[i] = getRandomNumber(0, MAX_HAND);
		for(j = 0; j < g->handCount[i]; j++){
			g->hand[i][j] = getRandomNumber(0, 27);
			if(g->hand[i][j] == 27) g->hand[i][j] = 26;
		}

	}
}

void randomizeDecks(struct gameState *g){
	int players = g->numPlayers;
	int i, j;
	for(i=0; i < players; i++){
		g->deckCount[i] = getRandomNumber(0, MAX_DECK);
		for(j = 0; j < g->deckCount[i]; j++){
			g->deck[i][j] = getRandomNumber(0, 27);
			if(g->deck[i][j] == 27) g->deck[i][j] = 26;
		}

	}
	
}

void randomizeDiscard(struct gameState *g){
	int players = g->numPlayers;
	int i, j;
	for(i=0; i < players; i++){
		g->discardCount[i] = getRandomNumber(0, MAX_DECK);
		for(j = 0; j < g->discardCount[i]; j++){
			g->discard[i][j] = getRandomNumber(0, 27);
			if(g->discard[i][j] == 27) g->discard[i][j] = 26;
		}

	}
	
}
void randomizeTurn(struct gameState *g){
	g->whoseTurn = getRandomNumber(0, g->numPlayers);
}

int makeRandomGameState(struct gameState *g){
//	printf("Randomizing Game\n");
	g->numPlayers = getRandomNumber(2, 5);
	if(g->numPlayers == 5) g->numPlayers = 4;
	randomizeSupply(g);
	randomizeDecks(g);
	randomizeDiscard(g);
	randomizeHands(g);
	randomizeTurn(g);
	g->coins = getRandomNumber(0, 20);
//	printf("Game Randomized\n");
	return 0;
}

int testDrawCard(struct gameState *g){
	int deckEmpty = 0;
	int player = getRandomNumber(0, (g->numPlayers));
	if (player == g->numPlayers) 
		player --;
	struct gameState gss;
	struct gameState *gs = &gss;
	memcpy(gs, g, sizeof(struct gameState));
	if(g->deckCount[player] <= 0){
		deckEmpty = 1;
	}

	int result = drawCard(player, g);
	if(result < 0){
		printf("-1 returned\n");
		return -1;
	}
	if(g->handCount[player] != (gs->handCount[player])+1){
		printf("Card not added correctly. Hand before: %d after %d\n", gs->handCount[player], g->handCount[player]);
	}
	if(!deckEmpty){
		if(g->deckCount[player] != (gs->deckCount[player] - 1)){
			printf("Card not removed from the deck.  Deck before: %d after %d\n", gs->deckCount[player], g->deckCount[player]);
		}
	}
	return 1;
}

int main(int argc, char** argv){
	int strm = 1, seed = 4, min = 2, max = 50;
	if(argc > 1){
		strm = atoi(argv[1]);
	}
	if(argc > 2){
		seed = atoi(argv[2]);
	}
	if(argc > 3){
		min = atoi(argv[3]);
	}
	if(argc > 4){
		max = atoi(argv[4]);
	}
	prepRandom(strm, seed);
	int i;
	struct gameState *g = newGame();
	for(i=0; i < 1000000; i++){
	
		makeRandomGameState(g);
		testDrawCard(g);
	}
	
	printf("test complete\n");
	return 0;
}
